package adminService

import (
	"errors"
	"gin-gorm-oj/define"
	"gin-gorm-oj/models"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"gorm.io/gorm"
	"net/http"
	"strconv"
	"time"
)

type SetmealCO struct {
	gorm.Model
	ID            int                   `gorm:"column:id;type:int(11);" json:"id"`
	Name          string                `gorm:"column:name;type:varchar(32);" json:"name"`
	Price         float64               `gorm:"column:price;type:decimal(10,2);" json:"price"`
	Status        *int                  `gorm:"column:status;type:int(2);" json:"status"`
	CategoryId    int                   `gorm:"column:category_id;type:int(11);" json:"category_id"`
	Image         string                `gorm:"column:image;type:varchar(255);" json:"image"`
	Description   string                `gorm:"column:description;type:varchar(255);" json:"description"`
	UpdateTime    time.Time             `gorm:"column:updated_at;type:datetime;" json:"update_time"`
	CategoryName  string                `gorm:"column:category_name;type:varchar(32);" json:"category_name"`
	SetmealDishes []*models.SetmealDish `gorm:"foreignKey:setmeal_id;references:id" json:"setmeal_dishes"`
}

func SaveSetmeal(c *gin.Context) {
	var setmealCO SetmealCO

	if err := c.ShouldBindJSON(&setmealCO); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	setmeal := new(models.Setmeal)
	copier.Copy(&setmeal, &setmealCO)
	setmeal.Status = &define.DEFAULT_STATUS_ENABLE

	if err := models.Db.Create(&setmeal).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "服务器错误",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "Save Success",
	})

}

func SetmealPageList(c *gin.Context) {
	page, err := strconv.Atoi(c.DefaultQuery("page", define.DefaultPage))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", define.DefaultSize))
	name := c.Query("name")
	status := -1
	categoryId, _ := strconv.Atoi(c.Query("categoryId"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	statusStr := c.Query("status")
	if statusStr != "" {
		status, _ = strconv.Atoi(statusStr)
	}
	page = (page - 1) * pageSize
	var total int64
	var setmealList []*SetmealCO

	db := models.Db.Model(&models.Setmeal{}).
		Table("setmeal s").
		Select("s.*, c.name as category_name").
		Joins("left join category c on s.category_id = c.id").
		Joins("left join setmeal_dish sd on s.id = sd.setmeal_id").
		Preload("SetmealDishes")

	if name != "" {
		db = db.Where("s.name like ?", "%"+name+"%")
	}
	if status != -1 {
		db = db.Where("s.status = ?", status)
	}
	if categoryId != 0 {
		db = db.Where("s.category_id = ?", categoryId)
	}

	db.Count(&total)
	db.Offset(page).Limit(pageSize).Order("s.updated_at desc").Find(&setmealList)

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"data": map[string]interface{}{
			"total":   total,
			"records": setmealList,
		},
	})
}

func DeleteSetmealByIds(c *gin.Context) {
	// 获取 ids
	ids := c.QueryArray("ids")

	// 使用事务
	err := models.Db.Transaction(func(tx *gorm.DB) error {
		for _, id := range ids {
			var dbSetmeal models.Setmeal

			// 查询单个套餐
			if err := tx.Where("id = ?", id).First(&dbSetmeal).Error; err != nil {
				return err
			}

			// 检查套餐状态
			if *dbSetmeal.Status == define.DEFAULT_STATUS_ENABLE {
				return errors.New("套餐在售，不能删除")
			}
			tx.Where("setmeal_id = ?", id).Delete(&models.SetmealDish{})

			tx.Where("id = ?", id).Delete(&models.Setmeal{})
		}

		// 返回 nil 表示事务提交成功
		return nil
	})

	// 处理事务结果
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "删除成功",
	})
}

func UpdateById(c *gin.Context) {
	var setmealCO SetmealCO
	if err := c.ShouldBindJSON(&setmealCO); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数错误",
		})
		return
	}
	setmeal := new(models.Setmeal)
	copier.Copy(&setmeal, &setmealCO)
	models.Db.Where("id = ?", setmeal.Id).Updates(&setmeal)

	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "更新成功",
	})
}
